package com.jinke.api.modules.third.changYunShip.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.common.util.CommonUtil;
import com.jinke.api.common.util.Global;
import com.jinke.api.modules.app.enums.BalanceLogType;
import com.jinke.api.modules.app.enums.OrderStatus;
import com.jinke.api.modules.app.enums.OrderType;
import com.jinke.api.modules.app.enums.ValidateStatus;
import com.jinke.api.modules.app.model.Order;
import com.jinke.api.modules.app.model.OrderParcel;
import com.jinke.api.modules.app.response.CreateLabel2Response;
import com.jinke.api.modules.app.service.IUserOrderTaskService;
import com.jinke.api.modules.app.service.OrderParcelService;
import com.jinke.api.modules.app.service.OrderService;
import com.jinke.api.modules.app.service.UserRechargeService;
import com.jinke.api.modules.app.util.MathUtil;
import com.jinke.api.modules.app.util.OssUtil;
import com.jinke.api.modules.base.service.ThirdService;
import com.jinke.api.modules.third.changYunShip.model.response.ChangYunShipCreateOrderResponse;
import com.jinke.api.modules.third.changYunShip.model.response.ChangYunShipGetPriceResponse;
import com.jinke.api.modules.third.changYunShip.service.IChangYunShipService;
import com.jinke.api.modules.third.changYunShip.util.ChangYunShipUtils;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.ezeeship.model.response.CreateLabelResponse;
import com.jinke.api.modules.third.ezeeship.model.response.EstimateRateResponse;
import com.jinke.api.modules.third.ezeeship.service.EzeeShipService;
import com.jinke.api.modules.third.ezeeship.util.EzeeShipUtil;
import com.jinke.api.modules.ums.model.Channel;
import com.jinke.api.modules.ums.model.UmsAdmin;
import com.jinke.api.modules.ums.service.IApiLogService;
import com.jinke.api.modules.ums.service.UmsAdminService;
import com.jinke.api.modules.ums.vo.UserChannelVO;
import com.jinke.api.security.util.ApiUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author huang
 * @data 2024-05-07
 */
@Slf4j
@Service
public class ChangYunShipServiceImpl implements IChangYunShipService {
    @Resource
    private ThirdService thirdService;
    @Resource
    private UserRechargeService userRechargeService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderParcelService orderParcelService;
    @Resource
    private ChangYunShipUtils changYunShipUtils;
    @Resource
    private EzeeShipService ezeeShipService;
    @Resource
    private UmsAdminService umsAdminService;
    @Resource
    private OssUtil ossUtil;
    @Resource
    private IUserOrderTaskService iUserOrderTaskService;

    @Override
    public CommonResult estimateRate(EstimateRateRequest request) {
        Integer  userId = ApiUserUtil.getUserId();
        return estimateRate(request, userId);
    }

    @Override
    public CommonResult estimateRate(EstimateRateRequest request, Integer userId) {
        UserChannelVO userChannelVO = request.getUserChannelVO();
        BigDecimal rate = getPriceAmount(request, userId, userChannelVO);
        if (rate.compareTo(new BigDecimal("0")) > 0) {
            EstimateRateResponse.Data newData = new EstimateRateResponse.Data();
            newData.setRate(rate);
            return CommonResult.success(newData);
        }
        return CommonResult.failed();
    }

    private BigDecimal getPriceAmount(EstimateRateRequest request, Integer userId, UserChannelVO vo) {
        String result =   changYunShipUtils.getPrice(request);
        BigDecimal rate = new BigDecimal("0");
        if (StringUtils.isNotEmpty(result)) {
            List<ChangYunShipGetPriceResponse> responseList = JSONUtil.toList(result, ChangYunShipGetPriceResponse.class);
            List<ChangYunShipGetPriceResponse> collect = responseList.stream().filter(x -> x.getTransportChannelTypeCode().equals(vo.getChannel().getChannelName())).collect(Collectors.toList());
            ChangYunShipGetPriceResponse response = collect.get(0);
            if (ObjectUtils.isNotEmpty(response)) {
                BigDecimal price = response.getSalePrice();
                rate = thirdService.calcRate(userId, vo, price);
            }
        }
        return rate;
    }

    @Override
    public CommonResult createLabel(EstimateRateRequest request) {

        Integer userId = ApiUserUtil.getUserId();

        return createLabel(request, userId);
    }


    @Override
    public CommonResult createLabel(EstimateRateRequest request, Integer userId) {
        if (StringUtils.isBlank(request.getOrderNO())) {
            String orderNo = CommonUtil.getOrderNo();
            request.setOrderNO(orderNo);
        }
        UserChannelVO userChannelVO = request.getUserChannelVO();
        Channel channel = userChannelVO.getChannel();
        ezeeShipService.fillResidential(request, userId);
        //预估用户下单金额
        BigDecimal rate = getPriceAmount(request, userId, userChannelVO);
        UmsAdmin umsAdmin = umsAdminService.getById(userId);
        if (rate.compareTo(new BigDecimal("0")) == 0 || ObjectUtils.isEmpty(umsAdmin)) {
            return CommonResult.failed("数据异常");
        }
        //计算当前用户实际可支配金额
        BigDecimal totalAmount = umsAdmin.getBalance().add(umsAdmin.getCreditBalance());
        if (totalAmount.compareTo(rate)<0){
            return CommonResult.failed("Insufficient Balance");
        }

        String result =   changYunShipUtils.createOrder(request);
        if (ObjectUtils.isNotEmpty(result)) {
            ChangYunShipCreateOrderResponse response;
            try {
                response = JSONUtil.toBean(result, ChangYunShipCreateOrderResponse.class);
                //有返回错误信息，说明下单失败
                if (StringUtils.isNotEmpty(response.getErrorMsg())) {
                    return CommonResult.failed(response.getErrorMsg());
                }
            } catch (Exception e) {
                //解析出现异常。说明下单失败
                return CommonResult.failed(result);
            }
            if (StringUtils.isNotEmpty(response.getSourceNo()) && StringUtils.isNotEmpty(response.getLabelFileUrl())) {

                BigDecimal afterRate = thirdService.calcRate(userId, request.getUserChannelVO(), response.getAmount());

                //扣钱
                if (ObjectUtils.isNotEmpty(afterRate) && BigDecimal.ZERO.compareTo(afterRate) < 0) {
                    userRechargeService.decrTransfer(userId, afterRate, BalanceLogType.CONSUME, "寄件", request.getOrderNO(),request.getObjectId(),channel,null);
                }

                Order order = new Order();
                order.setRate(afterRate);

                //设置错误信息为空
                order.setErrMsg("");
                order.setServiceCode(channel.getChannelCode());
                order.setChannelId(channel.getId());
                if (ObjectUtils.isNotEmpty(umsAdmin.getSellerId())) {
                    order.setSellerId(umsAdmin.getSellerId());
                }
                order.setId(request.getOrderId());
                order.setUserId(userId);
                order.setOrderNo(request.getOrderNO());
                order.setOriginFee(response.getAmount());
                order.setPlatformNo(response.getSourceNo());
                order.setObjectId(response.getInvoiceId());
                //上传pdf文件
                ossUtil.upload("pdf", response.getInvoiceId() + ".pdf", response.getLabelFileUrl());
                String newPdfUrl = Global.PRINT_LABEL_API + response.getInvoiceId();
                //更新一遍地址信息
                order.setFromCity(request.getFrom().getCity());
                order.setFromEmail(request.getFrom().getEmail());
                order.setFromCompany(request.getFrom().getCompany());
                order.setFromPhone(request.getFrom().getPhone());
                order.setFromAddressLine2(request.getFrom().getAddressLine2());
                order.setFromAddressLine1(request.getFrom().getAddressLine1());
                order.setFromCountryCode(request.getFrom().getCountryCode());
                order.setFromZipCode(request.getFrom().getZipCode());
                order.setFromPersonName(request.getFrom().getPersonName());
                order.setFromStateCode(request.getFrom().getStateCode());

                try {
                    order.setReference(request.getExtra().getReference());
                    order.setReference2(request.getExtra().getReference2());
                }catch (Exception e){
                    log.error("设置reference出错了");
                }

                
                EstimateRateRequest.Address requestTo = request.getTo();
                order.setToCity(requestTo.getCity());
                order.setToEmail(requestTo.getEmail());
                order.setToCompany(requestTo.getCompany());
                order.setToPhone(requestTo.getPhone());
                order.setToAddressLine2(requestTo.getAddressLine2());
                order.setToAddressLine1(requestTo.getAddressLine1());
                order.setToCountryCode(requestTo.getCountryCode());
                order.setToZipCode(requestTo.getZipCode());
                order.setToPersonName(requestTo.getPersonName());
                order.setToStateCode(requestTo.getStateCode());
                order.setOrderType(OrderType.API);
                order.setPdfUrl(newPdfUrl);
                order.setStatus(OrderStatus.RECENT.getValue());
                order.setValidateStatus(ObjectUtils.isNotEmpty(requestTo.getIsValid()) && requestTo.getIsValid() ? ValidateStatus.defaultEnum(requestTo.getIsResidential()) : ValidateStatus.UN_VALIDATE);
                //保证金比列
                BigDecimal earnestRate = umsAdmin.getEarnestRate();
                //计算保证金
                BigDecimal subEarnestBalance = MathUtil.formatBigDecimal(afterRate.multiply(earnestRate));
                order.setEarnest(subEarnestBalance);

                //保存订单信息
                orderService.saveOrUpdate(order);

                //定时任务表插入一条数据
                Integer orderId = order.getId();
                iUserOrderTaskService.saveByOrderId(orderId);
                //更新包裹信息
                updateParcel(request, userId,   newPdfUrl,response.getSourceNo(), orderId);


                CreateLabelResponse.Data newCreateLabelResponseData = new CreateLabelResponse.Data();
                newCreateLabelResponseData.setRate(afterRate);

                CreateLabel2Response.FeeDetail newFeeDetail = new CreateLabel2Response.FeeDetail();
                newFeeDetail.setBaseRate(afterRate);
                newCreateLabelResponseData.setFeeDetail(newFeeDetail);

                newCreateLabelResponseData.setRate(afterRate);
                newCreateLabelResponseData.setStatus(1);
                newCreateLabelResponseData.setCreateTime(LocalDateTime.now());
                newCreateLabelResponseData.setObjectId(response.getInvoiceId());
                newCreateLabelResponseData.setPdfUrl(newPdfUrl);
                newCreateLabelResponseData.setTrackingNumber(Collections.singletonList(response.getSourceNo()));
                String labelUrl = Global.PRINT_LABEL_API + response.getInvoiceId();
                newCreateLabelResponseData.setLabelUrl(Collections.singletonList(labelUrl));
                return CommonResult.success(newCreateLabelResponseData);
            } else {
                //面单和追踪号都为空则下单异常
                return CommonResult.failed("下单失败！！！");
            }
        }
        return CommonResult.failed("下单失败！！！");
    }

    /**
     * 更新包裹信息
     * @param request
     * @param userId
     * @param newPdfUrl
     * @param trackingNumber
     * @param orderId
     */
    @Transactional
    void updateParcel(EstimateRateRequest request, Integer userId,  String newPdfUrl, String trackingNumber, Integer orderId) {
        List<EstimateRateRequest.Parcel> parcels = request.getParcels();
        List<OrderParcel> orderParcels = parcels.stream().map(x -> {
            OrderParcel orderParcel = new OrderParcel();
            orderParcel.setOrderId(orderId);
            orderParcel.setUserId(userId);
            BeanUtils.copyProperties(x, orderParcel);
            EstimateRateRequest.Extra extra = x.getExtra();
            if (extra != null) {
                BeanUtils.copyProperties(extra, orderParcel);
            }
            return orderParcel;
        }).collect(Collectors.toList());
        //删除订单下原来的包裹
        orderParcelService.remove(new LambdaQueryWrapper<OrderParcel>().eq(OrderParcel::getOrderId, orderId));
        for (OrderParcel orderParcel : orderParcels) {
            orderParcel.setTrackingNumber(trackingNumber);
            orderParcel.setLabelUrl(newPdfUrl);
        }
        orderParcelService.saveBatch(orderParcels);
    }

    @Override
    public CommonResult getLabel(String objectId) {
        return null;
    }

    @Override
    public CommonResult getLabel(String objectId, Integer userId) {
        return null;
    }

    @Override
    public CommonResult cancelLabel(String objectId,String orderNo) {
        changYunShipUtils.cancel(objectId, orderNo);
        return CommonResult.success();
    }

    @Override
    public CommonResult tracking(String trackingNumber) {
        return null;
    }

    @Override
    public CommonResult cancelInsurance(String insuranceId) {

        return CommonResult.success();
    }
}
